﻿module Lab2_2
open Iteration
let (++) (a: 'a list) (b: 'a list) = List.map2 (+) a b
let enough x_next x = 
  List.map2 (fun a b -> abs(a-b)) x_next x |> List.max

// Newton functions
let newton_enough accuracy x_next x =
  (enough x_next x) <= accuracy

let newton_step f1 f2 f11 f22 f12 f21 (x:float list) =
  let tx = (x.[0], x.[1])
  x ++ cramer2x2 [
              [f11 tx; f21 tx;]; 
              [f12 tx; f22 tx;];
              [-f1(tx); -f2(tx);]
            ]
//EI functions
let ei_enough q accuracy x_next x = 
  (q / (1.0 - q)) * (enough x_next x) <= accuracy

let ei_step f1 f2 (x:float list) =
  let tx = (x.[0], x.[1])
  [f1 tx; f2 tx]

//Lab 2.2 functions
let f1 (x1, x2) = x1 - cos(x2) - 3.0
let f2 (x1, x2) = x2 - sin(x1) - 3.0
let f11 (x1, x2) = 1.0
let f22 (x1, x2) = 1.0
let f12 (x1, x2) = sin(x2)
let f21 (x1, x2) = -cos(x1)

let g1 (x1, x2) = cos(x2) + 3.0
let g2 (x1, x2) = sin(x1) + 3.0

let newton_solution accuracy = 
  solve (newton_step f1 f2 f11 f22 f12 f21) (newton_enough accuracy) [2.4; 4.0]
let ei_solution accuracy =
  solve (ei_step g1 g2) (ei_enough 0.7 accuracy) [2.4; 4.0]